package sk.tuke.constraintbuilder.views.components;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBException;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.widgets.FormToolkit;

import sk.tuke.constraintbuilder.model.ConstraintPatterns;
import sk.tuke.constraintbuilder.model.ConstraintPatterns.ConstraintPattern;
import sk.tuke.constraintbuilder.utils.MyUtils;

public class RuleChooserPanel extends Composite {

	private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
	
	//Rules properties
	ConstraintPatterns patterns;
	
	//List of all labels
	List<Label> listOfLabels = new ArrayList<>();
	
	public RuleChooserPanel(Composite parent, int style) {
		super(parent, style);
		try {
			patterns = MyUtils.getConstraintPatterns();
			initializePanel();
		} catch (JAXBException e) {
			MessageDialog.openError(getShell(), "Error", "Could not read property file!");
			e.printStackTrace();
		}
	}

	public void initializePanel() {
		addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				toolkit.dispose();
			}
		});
		toolkit.adapt(this);
		toolkit.paintBordersFor(this);
		GridLayout gridLayout = new GridLayout(4, false);
		setLayout(gridLayout);
		
		//Mouse and DND Listeners
		RuleChooserMouseListener listener = new RuleChooserMouseListener();
		DragSourceAdapter DNDListener = new DragSourceAdapter() {
			@Override
			public void dragSetData(DragSourceEvent event) {
				DragSource ds = (DragSource) event.widget;
				if(ds.getControl() instanceof Label){
					Label label = ((Label) ds.getControl());
					String value = label.getText();
					Object ruleType = null;
					value = (String) label.getData("value");
					ruleType = label.getData("ruletype");
					if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
						event.data = value+":"+ruleType;
					}
				}
			}
		};
		int operations = DND.DROP_MOVE | DND.DROP_COPY;
		DragSource source;
		Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
				
		//Create labels for each rule
		//Set text, tooltip, mouse listener, dnd listener, datas for dnd, layout properties
		for (ConstraintPattern pattern : patterns.getPatterns()) {
			Composite composite = new Composite(this, SWT.BORDER);
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
			toolkit.adapt(composite);
			toolkit.paintBordersFor(composite);
			GridLayout gl_composite = new GridLayout(1, false);
			gl_composite.marginWidth = 0;
			gl_composite.marginHeight = 0;
			composite.setLayout(gl_composite);
			
			Label label = new Label(composite, SWT.NONE);
			label.setText(pattern.getTitle());
			label.setToolTipText("TODO: Tooltiptext");
			label.setData("value", pattern.getName());
			label.setData("ruletype", RuleType.STANDARD);
			
			label.addMouseTrackListener(listener);
			source = new DragSource(label, operations);
			source.setTransfer(types);
			source.addDragListener(DNDListener);
			
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
			toolkit.adapt(label, true, true);
			listOfLabels.add(label);
		}
		
		Composite composite_14 = new Composite(this, SWT.NONE);
		composite_14.setLayout(new RowLayout(SWT.HORIZONTAL));
		composite_14.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 4, 1));
		toolkit.adapt(composite_14);
		toolkit.paintBordersFor(composite_14);
		
		Button button = new Button(composite_14, SWT.RADIO);
		button.setSelection(true);
		button.setText("Standard rule");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				setRuleType(RuleType.STANDARD);
			}
		});
		toolkit.adapt(button, true, true);
		
		Button btnNegativeRule = new Button(composite_14, SWT.RADIO);
		toolkit.adapt(btnNegativeRule, true, true);
		btnNegativeRule.setText("Negative rule");
		btnNegativeRule.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				setRuleType(RuleType.NEGATIVE);
			}
		});
		
		Button btnChoice = new Button(composite_14, SWT.RADIO);
		toolkit.adapt(btnChoice, true, true);
		btnChoice.setText("Choice (at least one of)");
		btnChoice.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				setRuleType(RuleType.CHOICE);
			}
		});
	}
	
	private void setRuleType(RuleType ruleType){
		for (Label label : listOfLabels) {
			label.setData("ruletype", ruleType);
		}
	}
	
	enum RuleType{
		STANDARD, NEGATIVE, CHOICE;
	}
	
	

}
